﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ElfTyping.Animations;
using Microsoft.Xna.Framework;
using ElfTyping.General;
using ElfTyping.Cards;
using ElfTyping.States.GameState.Entities;

namespace ElfTyping.States.GameState
{
    public class EndOfChapterState : State
    {
        static string[] VictoryQuotes = { "Ha! That was nothing for an archer like myself!",
                                          "Their inexperience was their undoing!",
                                          "I hope Rolf learned something while watching!",
                                          "I fight for my friends Ike, but only the cute ones!",
                                          "I can feel the Elven strength flowing through me!",
                                          "Do you want to feel my muscles?",
                                          "Who wants to order Shinon a round for a job well done?",
                                          "You think you're so great Ike? I'm the hero now!",
                                          "An uke in need should have a brute, indeed!",
                                          "After all this, I'm going to an Elven Archer party."
                                        };
        const float Booster_RevealWait = 2.5f;

        static Animation Background = new Animation(@"Textures\GameState\EndOfChapter");
        static Rectangle BgRect = new Rectangle(0, 0, 800, 600);

        static Animation RewardWindowImage = new Animation(@"Textures\Text_Window_CT", new Rectangle(8, 448, 256, 80));
        static Rectangle RewardWindowRect = new Rectangle(50, 150, 400, 200);

        static Point[] BoosterCardCenter = { new Point(125, 150), new Point(400, 150), new Point(675, 150), new Point(175, 450), new Point(625, 450) };

        static Rectangle[] Choices = { new Rectangle(298, 360, 204, 63), new Rectangle(298, 470, 204, 63) };
        static Animation ButtonAnimation = new Animation(@"Textures\Text_Window_CT", new Rectangle(8, 184, 255, 79));
        static Animation SelectedButtonAnimation = new Animation(@"Textures\Text_Window_CT", new Rectangle(8, 360, 255, 79));

        enum Screen
        {
            VictoryQuote = 0,
            ExperienceTally,
            WaitingToOpenBooster,
            OpeningBooster,
            CampOrContinue
        }

        TextBox TextBox = new TextBox();
        FireEmblemPortraitAnimation ShinonPortrait = new ShinonPortrait(true);
        FireEmblemPortraitAnimation ShinonSmallPortrait = new ShinonPortrait(false);
        Point ShinonBottomLeft = FireEmblemPortraitAnimation.BigPortraitRightPosition;

        bool IsCompleted { get; set; }
        GameState GameState { get; set; }
        string VictoryQuote { get; set; }
        Screen CurrentScreen { get; set; }

        Rewards ChapterRewards;
        Rewards TotalRewards;
        List<Card> BoosterPack;
        float TimeLeftInRevealScreen;
        float TimeLeftToNextReveal;
        int RevealCardIndex;
        int PreviousLevel;
        int PreviousHealth;
        int PreviousStrength;
        int CampOrContinueChoice = 0;

        public EndOfChapterState(GameState gameState, bool isCompleted)
            : base()
        {
            ShinonPortrait.IsBlinking = true;
            IsCompleted = isCompleted;
            GameState = gameState;

            if (IsCompleted)
            {
                ChapterRewards = RewardsMap[new Point(gameState.QuestNumber, gameState.ChapterNumber)];
            }
            else
            {
                ChapterRewards = new Rewards(0, 0, 0, 0);
            }
            
            TotalRewards = ChapterRewards;
            Player player = gameState.Player;
            if (player != null)
            {
                TotalRewards.PuzzlePieces = TotalRewards.PuzzlePieces + player.PuzzlePiecesEarned;
                TotalRewards.Gold = TotalRewards.Gold + player.GoldEarned;
                TotalRewards.Experience = TotalRewards.Experience + player.ExperienceEarned;
            }

            int quoteIndex = new Random().Next(VictoryQuotes.Length);
            VictoryQuote = VictoryQuotes[quoteIndex];

            CurrentScreen = Screen.VictoryQuote;
        }

        public override void InitializeState()
        {
            //throw new NotImplementedException();
        }

        public override void Draw(Camera camera)
        {
            Background.Draw(camera, BgRect);
            
            /* Big Shinon */

            if (CurrentScreen <= Screen.ExperienceTally)
            {
                ShinonPortrait.IsSpeaking = (CurrentScreen == Screen.VictoryQuote);
                ShinonPortrait.DrawWithBottomLeft(camera, ShinonBottomLeft);
            }

            /* Title */

            if (CurrentScreen <= Screen.ExperienceTally)
            {
                Color titleColor = IsCompleted ? Color.ForestGreen : Color.IndianRed;
                string titleText = string.Format("Chapter {0}-{1} {2}", GameState.QuestNumber, GameState.ChapterNumber,
                    IsCompleted ? "Complete!" : "Failed");

                camera.MakeText(titleText)
                    .WithCenteredPosition(400, 75)
                    .WithColor(titleColor)
                    .WithFont(Camera.TextDrawer.TimesNewRomanVeryBigFont)
                    .Draw();
            }

            /* Rewards */

            if (CurrentScreen <= Screen.ExperienceTally)
            {
                StringBuilder rewardsText = new StringBuilder();
                rewardsText.AppendLine("Total Rewards:");
                if (TotalRewards.PuzzlePieces > 0)
                {
                    rewardsText.AppendLine(TotalRewards.PuzzlePieces + "Puzzle " + ((TotalRewards.PuzzlePieces > 1) ? "Pieces" : "Piece"));
                }
                if (TotalRewards.Gold > 0)
                {
                    rewardsText.AppendLine(TotalRewards.Gold + " Gold");
                }
                if (TotalRewards.Experience > 0)
                {
                    rewardsText.AppendLine(TotalRewards.Experience + " Experience");
                }
                if (TotalRewards.Boosters > 0)
                {
                    rewardsText.AppendLine(TotalRewards.Boosters + " Shinon Booster Packs");
                }

                RewardWindowImage.Draw(camera, RewardWindowRect);
                camera.MakeText(rewardsText.ToString())
                    .WithTopLeftPosition(65, 165)
                    .WithColor(Color.White)
                    .WithFont(Camera.TextDrawer.TimesNewRomanBigFont)
                    .Draw();
            }
            
            /* Booster Pack */

            if (CurrentScreen >= Screen.WaitingToOpenBooster)
            {
                for (int i = 0; i < BoosterPack.Count; i++)
                {
                    BoosterPack[i].Draw(camera, BoosterCardCenter[i]);
                }
            }

            /* Choices */
            if (CurrentScreen == Screen.CampOrContinue)
            {
                int otherChoice = (CampOrContinueChoice == 0) ? 1 : 0;                
                
                SelectedButtonAnimation.Draw(camera, Choices[CampOrContinueChoice]);
                ButtonAnimation.Draw(camera, Choices[otherChoice]);

                camera.MakeText("Return to Camp")
                    .WithCenteredPosition(Choices[0].Center)
                    .WithColor((otherChoice == 0) ? Color.White : Color.Yellow)
                    .WithFont(Camera.TextDrawer.TimesNewRomanBigFont)
                    .Draw();
                camera.MakeText("Continue")
                    .WithCenteredPosition(Choices[1].Center)
                    .WithColor((otherChoice == 1) ? Color.White : Color.Yellow)
                    .WithFont(Camera.TextDrawer.TimesNewRomanBigFont)
                    .Draw();
            }

            /* Text Box */

            TextBox.IsPortraitOnLeft = false;            
            if (CurrentScreen == Screen.VictoryQuote)
            {
                TextBox.Text = VictoryQuote;
            }
            else if (CurrentScreen == Screen.ExperienceTally)
            {
                PlayerStatus status = PlayerStatus.GetStatus();
                int expToNextLevel = PlayerStatus.GetExperienceUpToLevel(status.Level + 1) - status.TotalExperience;

                if (PreviousLevel != status.Level)
                {
                    TextBox.Text = string.Format("Yes! Level {0}! Level fucking up!\nMy Health grows from {1} to {2},\nand my Strength from {3} to {4}.\nOnly {5} more experience until level {6}!",
                        status.Level, PreviousHealth, status.MaximumHealth, PreviousStrength, status.Strength, expToNextLevel, status.Level + 1);
                }
                else
                {
                    TextBox.Text = string.Format("After gaining {0} last battle, I only need {1} more\nexperience until I level to {2} and grow more brutish!",
                        TotalRewards.Experience, expToNextLevel, status.Level + 1);
                }
            }
            else if (CurrentScreen == Screen.WaitingToOpenBooster)
            {
                TextBox.Name = "Shinon";
                TextBox.Portrait = ShinonSmallPortrait;
                TextBox.IsPortraitOnLeft = true;
                TextBox.Text = "You ready to crack this booster?";
            }

            if (CurrentScreen <= Screen.WaitingToOpenBooster)
            {
                TextBox.Draw(camera);
            }
        }

        public override void Tick(float dt)
        {
            if (CurrentScreen == Screen.OpeningBooster)
            {
                TimeLeftInRevealScreen -= dt;

                if (TimeLeftInRevealScreen < 0)
                {
                    CurrentScreen++;
                }
                else
                {
                    TimeLeftToNextReveal -= dt;
                    if (TimeLeftToNextReveal < 0 && RevealCardIndex < 5)
                    {
                        BoosterPack[RevealCardIndex].IsShowingFront = true;
                        TimeLeftToNextReveal += Booster_RevealWait;
                        RevealCardIndex++;
                    }
                }
            }

            ShinonPortrait.Advance(dt);
            base.Tick(dt);
        }

        public override void HandleInput(InputInfo inputInfo)
        {
            PlayerStatus status = PlayerStatus.GetStatus();

            if (inputInfo.IsKeyJustPressed(GameKey.Use))
            {
                if (CurrentScreen == Screen.VictoryQuote)
                {
                    PreviousLevel = status.Level;
                    PreviousHealth = status.MaximumHealth;
                    PreviousStrength = status.Strength;

                    /* Give player rewards! */
                    
                    foreach (Card card in TotalRewards.Cards)
                    {
                        CardManager.GetManager().FoundCard(card);
                    }

                    for (int i = 0; i < TotalRewards.PuzzlePieces; i++)
                    {
                        var piece = PuzzlePieceManager.GetManager().GenerateRandomPuzzlePiece();
                        PuzzlePieceManager.GetManager().FoundPiece(piece);
                    }

                    status.Gold = status.Gold + TotalRewards.Gold;
                    status.GainExperience(TotalRewards.Experience);

                    if (status.FurthestQuest < GameState.QuestNumber)
                    {
                        status.FurthestQuest = GameState.QuestNumber;
                        status.FurthestChapter = GameState.ChapterNumber;
                    }
                    else if ((status.FurthestQuest == GameState.QuestNumber) && (status.FurthestChapter < GameState.ChapterNumber))
                    {
                        status.FurthestChapter = GameState.ChapterNumber;
                    }

                    status.CurrentQuest = GameState.QuestNumber;
                    status.CurrentChapter = GameState.ChapterNumber + 1;                    
                    status.SaveToXml();
                }
                if (CurrentScreen == Screen.ExperienceTally)
                {
                    BoosterPack = CardManager.GetManager().GenerateBooster();
                    CardManager.GetManager().FoundBooster(BoosterPack);
                    PlayerStatus.GetStatus().SaveToXml();
                    foreach (Card card in BoosterPack)
                    {
                        card.IsShowingFront = false;
                    }
                }
                else if (CurrentScreen == Screen.WaitingToOpenBooster)
                {
                    TimeLeftInRevealScreen = Booster_RevealWait * 7;
                    TimeLeftToNextReveal = Booster_RevealWait;
                    RevealCardIndex = 0;
                }                

                if (CurrentScreen == Screen.CampOrContinue)
                {
                    if (CampOrContinueChoice == 0)
                    {
                        ChangeStateAfterTick(new CampState.CampState(), true);
                    }
                    else
                    {
                        ChangeStateAfterTick(new StoryState.StoryState(status.CurrentQuest, status.CurrentChapter), true);
                    }
                }
                else if (CurrentScreen <= Screen.WaitingToOpenBooster)
                {
                    CurrentScreen++;
                }
            } else if (inputInfo.IsKeyJustPressed(GameKey.Escape))
            {
                if (CurrentScreen == Screen.OpeningBooster)
                {
                    foreach (Card card in BoosterPack)
                    {
                        card.IsShowingFront = true;
                    }
                    CurrentScreen++;
                }
            }

            if (inputInfo.IsKeyJustPressed(GameKey.Up))
            {
                if (CurrentScreen == Screen.CampOrContinue && CampOrContinueChoice > 0)
                {
                    CampOrContinueChoice--;
                }
            }

            if (inputInfo.IsKeyJustPressed(GameKey.Down))
            {
                if (CurrentScreen == Screen.CampOrContinue && CampOrContinueChoice < 1)
                {
                    CampOrContinueChoice++;
                }
            }
            
        }

        private static Dictionary<Point, Rewards> RewardsMap = new Dictionary<Point, Rewards>()
        {
            {new Point(1, 1), new Rewards(2, 100, 20, 1)},
            {new Point(1, 2), new Rewards(2, 150, 30, 1)},
            {new Point(1, 3), new Rewards(2, 200, 40, 1)},
            {new Point(1, 4), new Rewards(2, 500, 50, 1)},
            {new Point(1, 5), new Rewards(2, 250, 60, 1)},
            {new Point(1, 6), new Rewards(2, 300, 70, 1)},
            {new Point(1, 7), new Rewards(2, 350, 80, 1)},
            {new Point(1, 8), new Rewards(5, 1000, 100, 1)},
        };

        private struct Rewards
        {
            public int PuzzlePieces { get; set; }
            public int Gold { get; set; }
            public int Experience { get; set; }
            public int Boosters { get; set; }
            public List<Card> Cards { get; set; }

            public Rewards(int pieces, int gold, int experience, int boosters) : this()
            {
                PuzzlePieces = pieces;
                Gold = gold;
                Experience = experience;
                Boosters = boosters;
                Cards = new List<Card>();
            }
        }
    }
}
